﻿//#define  _CRT_SECURE_NO_WARNINGS
//
//#include<iostream>
//using namespace std;
//初始化列表
//typedef int STDataType;
//class Stack
//{
//public:
//	Stack(int n)
//	{
//		cout << "Stack(int n = 4)" << endl;
//
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	
//	// st2(st1)
//	Stack(const Stack& st)
//	{
//		// 需要对_a指向资源创建同样大的资源再拷贝值
//		_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败!!!");
//			return;
//		}
//		memcpy(_a, st._a, sizeof(STDataType) * st._top);
//		_top = st._top;
//		_capacity = st._capacity;
//	}
//
//	// st1 = st3
//	// st1 = st1;
//	Stack& operator=(const Stack& st)
//	{
//		//避免自已给自已拷贝
//		if (this != &st)
//		{
//			free(_a);
//			_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
//			if (nullptr == _a)
//			{
//				perror("malloc申请空间失败!!!");
//				return *this;
//			}
//			memcpy(_a, st._a, sizeof(STDataType) * st._top);
//			_top = st._top;
//			_capacity = st._capacity;
//		}
//
//		return *this;
//	}
//
//	void Push(STDataType x)
//	{
//		if (_top == _capacity)
//		{
//			int newcapacity = _capacity * 2;
//			STDataType* tmp = (STDataType*)realloc(_a, newcapacity *
//				sizeof(STDataType));
//			if (tmp == NULL)
//			{
//				perror("realloc fail");
//				return;
//			}
//			_a = tmp;
//			_capacity = newcapacity;
//		}
//		_a[_top++] = x;
//	}
//
//	void Pop()
//	{
//		_a[_top - 1] = -1;
//		--_top;
//	}
//
//	int Top()
//	{
//		return _a[_top - 1];
//	}
//
//	~Stack()
//	{
//		cout << "~Stack()" << endl;
//		free(_a);
//		//_a = nullptr;
//		//_top = _capacity = 0;
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//
//class MyQueue
//{
//public:
//	//初始化列表是来初始化每个成员变量
//	// 本质上初始化列表是构造函数的一部分
//	//需要自定义类型的构造函数来初始化成员变量,初始化列表可以
//	MyQueue(int n, int& rx)
//		:_pushst(n)
//		, _popst(n)
//		, ref(rx)
//		, i(rx)
//	{
//		size = rx;
//	}
//
//private:
//	// 成员变量声明
//	Stack _pushst;
//	Stack _popst;
//
//	int& ref;//引用必须初始化
//	const int i;//const 引用
//	int size;
//};
//
//
//
//int main()
//{
//	int x = 10;
//	MyQueue q(1000,x);//这种写法在栈的有参构造函数就是错误的，必须要给成员变量_pushst,_popst初始化
//
//	//引用，常属性必须要先初始化
//	const int a = 1;
//	const int& ra = a;
//
//	return 0;
//}

/////////////////////////////////////////////////成员变量给缺省值
//#include<iostream>
//using namespace std;
//
//typedef int STDataType;
//class Stack
//{
//public:
//	Stack(int n)
//	{
//		cout << "Stack(int n = 4)" << endl;
//
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	
//	// st2(st1)
//	Stack(const Stack& st)
//	{
//		// 需要对_a指向资源创建同样大的资源再拷贝值
//		_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败!!!");
//			return;
//		}
//		memcpy(_a, st._a, sizeof(STDataType) * st._top);
//		_top = st._top;
//		_capacity = st._capacity;
//	}
//
//	// st1 = st3
//	// st1 = st1;
//	Stack& operator=(const Stack& st)
//	{
//		if (this != &st)
//		{
//			free(_a);
//			_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
//			if (nullptr == _a)
//			{
//				perror("malloc申请空间失败!!!");
//				return *this;
//			}
//			memcpy(_a, st._a, sizeof(STDataType) * st._top);
//			_top = st._top;
//			_capacity = st._capacity;
//		}
//
//		return *this;
//	}
//
//	void Push(STDataType x)
//	{
//		if (_top == _capacity)
//		{
//			int newcapacity = _capacity * 2;
//			STDataType* tmp = (STDataType*)realloc(_a, newcapacity *
//				sizeof(STDataType));
//			if (tmp == NULL)
//			{
//				perror("realloc fail");
//				return;
//			}
//			_a = tmp;
//			_capacity = newcapacity;
//		}
//		_a[_top++] = x;
//	}
//
//	void Pop()
//	{
//		_a[_top - 1] = -1;
//		--_top;
//	}
//
//	int Top()
//	{
//		return _a[_top - 1];
//	}
//
//	~Stack()
//	{
//		cout << "~Stack()" << endl;
//		free(_a);
//		//_a = nullptr;
//		//_top = _capacity = 0;
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//
//class MyQueue
//{
//public:
//	//初始化列表是来初始化每个成员变量
//	// 本质上初始化列表是构造函数的一部分
//	//需要自定义类型的构造函数来初始化成员变量,初始化列表可以
//	MyQueue(int n, int& rx)
//		: _pushst(n)
//		, _ref(rx)
//		,_arr((int*)malloc(40))
//	{
//		if(_arr == nullptr)
//			{
//				//...
//			}
//			else
//			{
//				for (size_t i = 0; i < 10; i++)
//				{
//					_arr[i] = i;
//				}
//			}
//	}
//private:
//	// 成员变量声明
//	//成员变量也可以给缺省值
// //没有显示用初始化列表初始化，默认使用缺省值初始化
//	Stack _pushst = 1000;
//	Stack _popst = 2000;
//
//	int& _ref ;//引用必须初始化
//	const int _i =1;
//	int* _arr = (int*)malloc(40);
//};
//
//
//int main()
//{
//	int x = 2;
//	MyQueue q(1000, x);
//	return 0;
//}

////////////////////////////////////////
//const 修饰成员函数
//const修饰成员函数隐含的this指针,确保this指针指向的值不会改变。明确只有成员函数才有this指针
//原本Date* const this----修饰指针本身
//const Date* const this---修饰值和指针都不会改变

//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	 void Print(const Date* const this) const
//	void Print() const
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//
//}
//int main()
//{
//	Date d1(2024, 1, 1);
//	d1.Print();//非const对象调用const是权限的缩小
//	const Date d2(2024, 1, 1); //const对象调用const是权限的平行
//	d2.Print();
//	//如果print成员函数无const,那么const对象不能调用print成员函数权限放大
//}
//


///////////////////取地址运算符重载

//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	// void Print(const Date* const this) const
//	void Print() const
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//	Date* operator&()
//	{
//		/*return nullptr;*/
//		return this;
//	}
//	const Date* operator&()const
//	{
//		//return this;
//		return (Date*)1212222;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//
//int main()
//{
//	const Date d1(2024, 11, 14);
//	cout << &d1 << endl;
//}

////////////////////赋值运算符重载
//两个存在对象的直接拷贝
//
//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	// void Print(const Date* const this) const
//	void Print() const
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//
//	Date& operator=(const Date& d)
//	{
//		//对于有资源的，自已给自已拷贝，这里就会出错
//		if (this != &d)
//		{
//			_year = d._year;
//			_month = d._month;
//			_day = d._day;
//		}
//	
//		return *this;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	//编译器会自动生成一个默认赋值运算符重载(浅拷贝)
//	//无资源不用显示实现，有资源需要显示实现
//	Date d1(2024, 11, 18);
//	Date d2(2024, 11, 11);
//	Date d3(2024, 11, 20);
//
//	d1 = d2 = d3;
//	d1.Print();
//	Date d3(2024, 7, 6);
//
//
//	d1 = d3;
//	// 需要注意这⾥是拷⻉构造，不是赋值重载 
//	// 请牢牢记住赋值重载完成两个已经存在的对象直接的拷⻉赋值 
//	// ⽽拷⻉构造⽤于⼀个对象拷⻉初始化给另⼀个要创建的对象 
//	Date d4 = d1;
//
//	return 0;
//}
//
/////////////////////////////////////////////
//
//class Time
//{
//public:
//	Time(int hour = 1, int min = 1, int sex = 1)
//	{
//
//	}
//private:
//	size_t _hour = 21;
//	size_t _min= 4;
//	size_t _sec = 12;
//};
//
//int main()
//{
//	Time t1;
//	return 0;
//}
//#include <iostream>
//using namespace std;
//
//class Time
//{
//public:
//	Time(int hour)
//		:_hour(hour)
//	{
//		cout << "Time()" << endl;
//	}
//private:
//	int _hour;
//};
//
//class Date
//{
//public:
//	Date(int& x, int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//		, _t(12)
//		, _ref(x)
//		, _n(1)
//	{
//		 error C2512: “Time”: 没有合适的默认构造函数可⽤ 
//		 error C2530 : “Date::_ref” : 必须初始化引⽤ 
//		 error C2789 : “Date::_n” : 必须初始化常量限定类型的对象 
//	}
//	void Print() const
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//	Time _t; // 没有默认构造 
//	int& _ref; // 引⽤ 
//	const int _n; // const 
//};
//
//int main()
//{
//	int i = 0;
//	Date d1(i);
//	d1.Print();
//	return 0;
//}


/////////////////////////////////////////
////类型转换
//#include<iostream>
//using namespace std;
//class A
//{
//public:
//	// 构造函数explicit就不再支持隐式类型转换
//	explicit A(int a1);
//	//三种构造函数方式支持对应的类型转换
//	//初始化列表
//	/*A(int a1)
//		:_a1(a1)
//	{}*/
//
//	A(int a1)
//	{
//		_a1 = a1;
//	}
//
//	A(const A& aa)
//		:_a1(aa._a1)
//		,_a2(aa._a2)
//	{
//		cout << "	A(const A& aa)" << endl;
//	}
//
//	//explicit A(int a1, int a2)
//	A(int a1, int a2)
//		:_a1(a1)
//		, _a2(a2)
//	{}
//
//	void Print()
//	{
//		cout << _a1 << " " << _a2 << endl;
//	}
//
//	int Get() const
//	{
//		return _a1 + _a2;
//	}
//
//private:
//	int _a1 = 1;
//	int _a2 = 2;
//};
//
//class B
//{
//public:
//	B(const A& a)
//	{
//		_b = a.Get();
//	}
//private:
//	int _b = 0;
//};
//
//class Stack
//{
//public:
//	void Push(const A& aa)
//	{}
//};
//
//
//int main()
//{
//	A aa1(10);
//	B bb1(aa1);
//
//	//构造⼀个A的临时对象，再⽤这个临时对象拷贝构造aa3
//	// 编译器遇到连续构造+拷贝构造->优化为直接构造 
//	//拿10构造一个临时对象，再拷贝回去，(被优化了)
// 
//	// 很像拷贝构造
//	A aa2 = 10;//调用1//构造+拷贝
//	A aa3 = aa1;
//	A aa4 = { 10,20 };//调用3
//
//	//类型转换会产生临时变量,//临时对象具有常性,引用的本质是引用的临时对象，要加const
//	const A& aa5 = 1;
//
//	Stack st;
//	st.Push(1);
//	st.Push({ 1,2 });
//	st.Push(aa1);
//	return	0;
//}


///////////////////////////////////////
//类型转换
//#include<iostream>
//using namespace std;
//class A
//{
//public:
//	A(int a1)
//	{
//		_a1 = a1;
//	}
//
//	A(const A& aa)
//		:_a1(aa._a1)
//		, _a2(aa._a2)
//	{
//		cout << "	A(const A& aa)" << endl;
//	}
//
//	//explicit A(int a1, int a2)
//	A(int a1, int a2)
//		:_a1(a1)
//		, _a2(a2)
//	{}
//
//	void Print()
//	{
//		cout << _a1 << " " << _a2 << endl;
//	}
//
//private:
//	int _a1 = 1;
//	int _a2 = 2;
//};
//
//int main()
//{
//	//构造+拷贝
//	A aa1 = 1; //调用1
//	A aa2 = aa1;//调用2
//	A aa3 = { 2,2 };//调用3
//	return 0;
//}
//
//#include <iostream>
//class A
//{
//public:
//	static int _Asum()
//	{
//		return _a3 + _a4;
//	}
//	int Getstatic()
//	{
//		return _a3;
//	}
//private:
//	int _a1 = 1;
//	int _a2 = 2;
//	static int _a3 ;
//	static int _a4;
//};
//
//int A::_a3 = 10;
//int A::_a4 = 10;
//
//int main()
//{
//	std::cout << sizeof(A) << std::endl;
//	std::cout << A::_Asum() << std::endl;
//}
//int main()
//{
//	A aa1(1);
//	B bb1 = aa1;//拿aa1构造一个临时对象，再拷贝回去，(被优化了)//这里很像拷贝构造函数
//}
//
//#include<iostream>
//using namespace std;
//class A
//{
//public:
//	A()
//	{
//		_Acout++;
//	}
//
//	A(const A& T)
//	{
//		_Acout++;
//	}
//	~A()
//	{
//		_Acout--;
//	}
//	static int GetCount()
//	{
//		return _Acout;
//	}
//private:
//	static int _Acout;
//	int size;
//};
//
////静态变量必须要在类外声明
//int A::_Acout = 0;
//
//int main()
//{
//	A aa1, aa2;
//	cout << A::GetCount() << endl;
//	A aa3 = aa2;
//	cout << A::GetCount() << endl;
//}

//友元
//#include<iostream>
//using namespace std;
//
//class A
//{
//public:
//
//	A(int n = 1) 
//		: _a1(n)
//		,_a2(n)
//	{
//
//	}
//	friend void fun1(const A& a);
//	friend class B;
//private:
//	int _a1;
//	int _a2;
//};
//
//void fun1(const A& a)
//{
//	cout <<a._a1<<a._a2<< endl;
//}
//
//class B
//{
//public:
//	void fun1(const A& a,const B& b)
//	{
//		//访问A
//		cout << a._a1 << a._a2 << endl;
//		//访问B
//		cout << b._b1 << b._b2 << endl;
//	}
//
//private:
//	int _b1 = 0;
//	int _b2 = 0;
//};
//
//int main()
//{
//	 A aa1(10);
//	fun1(aa1);
//	B bb1;
//	bb1.fun1(aa1,bb1);
//
//	return 0;
//}
//#include<iostream>
//using namespace std;
//
//
//class A
//{
//private:
//	static int _k;
//	int _h = 1;
//
//public:
//	A(int n)
//	{
//		_h = n;
//	}
//
//	class B //B默认就是A的友元
//	{
//	public:
//		void foo(const A& a)
//		{
//			cout << _k << endl; //OK
//			cout << a._h << endl; //OK
//		}
//
//		int _b1 = 1;
//		int _b2 = 1;
//	};
//};
//int A::_k = 1;
//
//int main()
//{
//	cout << sizeof(A) << endl;
//	//定义b类对象
//	A::B bb1;
//	//传10发生了隐示转换，需要对应的构造函数
//	bb1.foo(10);//调用B类成员函数
//
//	return 0;
//}

//
////匿名对象
//#include <iostream>
//using namespace std;
//class A
//{
//public:
//	A(int a = 0)
//		:_a(a)
//	{
//		cout << "A(int a)" << endl;
//	}
//	~A()
//	{
//		cout << "~A()" << endl;
//	}
//private:
//	int _a;
//};
//class Solution {
//public:
//	int Sum_Solution(int n) {
//		//...
//		return n;
//	}
//};
//
////匿名对象做缺省参数
////void fun1(const A& a = A());
//void fun1(const A& a = A(10))
//{
//
// }
//int main()
//{
//	A aa1;
//	// 不能这么定义对象，因为编译器⽆法识别下⾯是⼀个函数声明，还是对象定义 
//	//A aa1();
//	// 但是我们可以这么定义匿名对象，匿名对象的特点不⽤取名字， 
//	// 但是他的⽣命周期只有这⼀⾏，我们可以看到下⼀⾏他就会⾃动调⽤析构函数 
//	A();//匿名
//	A(1);//怒名
//	A aa2(2);//有名对象
//
//	A& ref1 = aa2;
//
//	// const引用会延长匿名对象的声明周期，匿名对象跟着引用走
//	const A& ref2 = A(1);//
//	//A& ref2 = A(1);//编译器会报错
//
//
//	Solution s1;
//	s1.Sum_Solution(10);
//	// 匿名对象在这样场景下就很好用
//	cout<<Solution().Sum_Solution(10)<<endl;//指向获取值，就消失
//
//
//	//匿名对象做缺省参数
//	fun1();
//	fun1(aa2);
//
//	return 0;
//}



#include<iostream>
using namespace std;
class A
{
public:
	A(int n = 0)
		:_a1(n)
		, _a2(n)
	{
		cout << "A(int n)" << endl;
	}
	A(const A& aa)
		:_a1(aa._a1)
		, _a2(aa._a2)
	{
		cout << "A(const A& aa)" << endl;
	}
	//引用返回,不然会多一层拷贝构造
	A& operator=(const A& aa)
	{
		cout << "A operator=(const A& aa)" << endl;
		if (&aa != this)
		{
			_a1 = aa._a1;
			_a2 = aa._a2;
		}
		return *this;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a1 = 1;
	int _a2 = 1;
};

void f1(A a)
{

}

A f2()
{
	//对象不存在，放在临时变量中，编译器作了优化，不会调用拷贝构造
	A a;
	return a;
}

A f2(A& a)
{
	//对象存在，如果不引用返回，会多一层拷贝构造
	return a;
}
int main()
{
	////隐式类型转换
	////构造+拷贝，直接优化为构造,编译器将临时变量的拷贝构造优化了，并且对临时变量的析构也没了
	//A aa1 = 1;

	////传值传参，应该是拷贝
	//f1(aa1);

	////传匿名对象+类型转换
	////调用构造+拷贝--编译器直接优化为构造
	//f1(1);
	//f1(A());

	//传返回值
	//构造+拷贝临时对象+拷贝构造->优化成了构造函数
	//A a2 = f2();

	//构造+拷贝临时对象+赋值运算符重载->优化成了构造函数+赋值运算符重载
	//A aa2;
	//aa2 = f2();

	A aa2;
	f2();

	return 0;

	//对于传值传参，传值返回(如果对象不存在，如果对象还存在，如赋值运算符重载，会多一层拷贝)，编译器都做了优化，省去了拷贝构造的过程
	//编译器绝大多数把拷贝构造优化了
}